package org.example.service.post.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.example.annotation.LogTrace;
import org.example.dao.dao.post.PImageDao;
import org.example.dao.dao.post.PPostDao;
import org.example.dao.dto.commom.UserInfo;
import org.example.dao.dto.post.PostDto;
import org.example.partten.builder.product.post.PPostDto;
import org.example.dao.dto.user.UserDto;
import org.example.dao.entity.post.PImage;
import org.example.dao.entity.post.PPost;
import org.example.exception.ParamLossErrorException;
import org.example.skytool.es.doc.EsDslUtil;
import org.example.utils.post.post.EsPostService;
import org.example.service.post.PostService;
import org.example.skytool.commom.ContextUtil;
import org.example.skytool.commom.IdWorker;
import org.example.skytool.oss.minio.MinioConstant;
import org.example.skytool.oss.minio.MinioUtil;
import org.example.utils.post.post.RedisPostService;
import org.example.utils.post.post.dto.EsPostCompletionDoc;
import org.example.utils.post.post.dto.EsPostSearchDoc;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author 22449
 */
@Service("postService")
public class PostServiceImpl implements PostService {

    @Resource
    private ContextUtil contextUtil;

    @Resource
    private RedisPostService redisPostService;

    @Resource
    private IdWorker idWorker;

    @Resource
    private MinioUtil minioUtil;

    @Resource
    private PPostDao pPostDao;

    @Resource
    private PImageDao pImageDao;

    @Resource
    private EsPostService esPostService;

    @Override
    @LogTrace
    public PPostDto addPostByImage(String content, Long themeId) {
        //不能上传类型为全部的帖子
        if (themeId == 0) {
            throw new ParamLossErrorException("不能上传themeId为0哦");
        }

        //获取参数构造post
        UserDto userDto = contextUtil.getLoginUser();


        Long id = idWorker.nextId();

        PPost pPost = new PPost(id, content, (themeId), userDto.getUser().getId());
        pPostDao.insert(pPost);

        //构造PostDto
        PPostDto postDto = new PPostDto();
        postDto.setUserInfo(new UserInfo(userDto));
        postDto.setPPost(pPost);

        //将发送的帖子上传到es，提供搜索
        esPostService.insertDocument(postDto);
        return postDto;
    }

    @Override
    @LogTrace
    public PImage addPostImage(Long postId, MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new ParamLossErrorException("没有上传图片");
        }
        //构造image
        PImage image = new PImage();
        image.setId(idWorker.nextId());
        image.setPostId(postId);
        image.setUrl(minioUtil.upload(file, MinioConstant.POST, postId.toString()));
        pImageDao.insert(image);
        return image;
    }

    @Override
    @LogTrace
    public IPage<PostDto> getPostByMine(Integer limit, Integer start) {
        List<PostDto> postDtos = pPostDao.getPostDtoByMine(contextUtil.getId(),start*limit,limit);
        Integer num = pPostDao.getPostDtoByMineNum(contextUtil.getId());
        IPage<PostDto> page = new Page<>();
        page.setTotal(num);
        page.setSize(limit);
        page.setCurrent(start);
        page.setRecords(postDtos);
        page.setPages((long) Math.ceil(num/limit));
        return page;
    }

    @Override
    @LogTrace
    public IPage<PostDto> getPostByThemeAndHot(Long themeId, Integer limit, Integer start) {
        return redisPostService.getHotPost(themeId.toString(),start,limit);
    }

    @Override
    @LogTrace
    public IPage<PostDto> getPostByTheme(Long themeId, Integer limit, Integer start) {
        return redisPostService.getCommomPost(themeId.toString(),start,limit);
    }
    @Override
    @LogTrace
    public Long transferPost(Long id) {
        return redisPostService.transmitPostCache(id.toString());
    }

    @Override
    @LogTrace
    public Long likePost(Long id) {
        Long likeNum = redisPostService.likePostCache(id.toString());
        return likeNum;
    }

    @LogTrace
    @Override
    public IPage<PostDto> searchPost(Integer isValid, Long themeId, String content, Integer limit, Integer start) {

        redisPostService.addPostHistory(content);
        esPostService.insertSearchContent(content);


        EsDslUtil.DslResult<EsPostSearchDoc> result = esPostService.searchDoc(isValid, themeId, content, start, limit);
        Long total = result.getTotal();
        IPage<PostDto> pages = new Page<>();
        pages.setTotal(total);
        pages.setSize(limit);
        pages.setCurrent(start);
        Set<String> ids = result.getHits().keySet();
        List<PostDto> postDtos = redisPostService.selectPostDtoList(new ArrayList<>(ids));
        pages.setRecords(postDtos);
        return pages;
    }
    @Override
    @LogTrace
    public void deletePost(Long id) {
        PPost post = pPostDao.selectById(id);
        post.setIsValid(0);
        post.setUpdateTime(new Date());
        pPostDao.updateById(post);
        redisPostService.delPostContent(id.toString());
    }
    @Override
    @LogTrace
    public PPost updatePost(Long id, String content, Long themeId) {
        PPost tPost = pPostDao.selectById((id));
        tPost.setContent(content);
        tPost.setThemeId((themeId));
        pPostDao.updateById(tPost);
        redisPostService.delPostContent(id.toString());
        return tPost;
    }
    @Override
    @LogTrace
    public PostDto clickPost(Long id) {
        redisPostService.clickPostCache(id.toString());
        List<String> list= new ArrayList<>();
        list.add(id.toString());
        List<PostDto> list1 = redisPostService.selectPostDtoList(list);
        return list1.get(0);
    }
    @Override
    @LogTrace
    public IPage<PostDto> getPostByRecommend(Long themeId, Integer limit, Integer start) {
        return redisPostService.getRecommendPost(themeId.toString(),start,limit);
    }
    @Override
    public List<String> getSearchHistory() {
        return redisPostService.getPostHistory();
    }

    @Override
    public List<String> getSearchRecommend() {
        return redisPostService.getPostHistory();
    }

    @Override
    public List<String> getSearchHotRank() {
        return redisPostService.getSearchHotTop10();
    }

    @Override
    public List<String> getSearchIntime(String content) {
        EsDslUtil.DslResult<EsPostCompletionDoc> list = esPostService.querySuggest(content);
        return list.getSuggest();
    }

    @Override
    public void clearSearchHistory() {
        redisPostService.removePostHistory();
    }

}
